Skip to content

feat(rest): add OAuth2 token refresh#801

Open
lovromazgon wants to merge 3 commits intoapache:mainfrom
lovromazgon:lovro/oauth2-token-refresh
Open

feat(rest): add OAuth2 token refresh#801
lovromazgon wants to merge 3 commits intoapache:mainfrom
lovromazgon:lovro/oauth2-token-refresh

Conversation

@lovromazgon
Copy link
Contributor

@lovromazgon lovromazgon commented Mar 18, 2026

Rework the REST catalog OAuth2 auth to cache tokens and refresh them lazily before expiry, avoiding failed requests due to stale tokens.

The refresh chain follows the Iceberg REST spec: token exchange → exchange with Basic auth → refresh_token grant → client_credentials. Auth failures (401/403/419) trigger a forced refresh and single retry that re-applies headers and re-signs SigV4 requests.

Add WithAudience and WithResource catalog options, sent on token exchange requests per the spec.

Rework the REST catalog OAuth2 auth to cache tokens and refresh them
lazily before expiry, avoiding failed requests due to stale tokens.

The refresh chain follows the Iceberg REST spec: token exchange →
exchange with Basic auth → refresh_token grant → client_credentials.
Auth failures (401/403/419) trigger a forced refresh and single retry
that re-applies headers and re-signs SigV4 requests.

Add WithAudience and WithResource catalog options, sent on token
exchange requests per the spec.
Comment on lines +44 to +58
type AuthHeaderContext interface {
AuthHeaderCtx(ctx context.Context) (string, string, error)
}

// AuthRefresher is an optional interface that an AuthManager may implement
// to support refreshing credentials when authentication fails. When the
// session transport receives a 401, 403, or 419 response and the auth
// manager implements this interface, it will call RefreshAuth and retry
// the request once with the new credentials.
type AuthRefresher interface {
// RefreshAuth forces a credential refresh, discarding any cached
// tokens. After a successful refresh, AuthHeader will return the
// new credentials.
RefreshAuth(ctx context.Context) error
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the AuthHeaderContext and AuthRefresher interfaces were added simply to keep AuthManager backward compatible. However, if the maintainers are open to changing AuthManager I could collapse the other interfaces into it and simplify the code a bit.

Copy link
Contributor

@rockwotj rockwotj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI #793

also related: #795

@lovromazgon
Copy link
Contributor Author

@rockwotj oh man, that's what I get for not opening an issue first and coordinating. It's the end of my day so I can have a look at the other PRs tomorrow to see how my changes fit in, if at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants